home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1996 #5
/
Amiga Plus CD - 1996 - No. 5.iso
/
pd
/
texte
/
thor_api
/
parsemsg
/
parsemsg.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-20
|
29KB
|
1,254 lines
/* parsemsg.c
Auto: smake -f src:bbsread/parsemsg/makefile
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/semaphores.h>
#include <libraries/dos.h>
#include <dos/dostags.h>
#include <utility/tagitem.h>
#include <utility/date.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/utility.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <libraries/bbsread.h>
#include <proto/bbsread.h>
#include <libraries/utgui.h>
#include <proto/utgui.h>
#include <libraries/reqtools.h>
#include <proto/reqtools.h>
#define ULONG_MAX 4294967295
#define BUFLEN 250
#define GRABLEN 100
#define NAMELENGTH 31
#define CSI "\x9b"
/* Global structure to hold librarybases */
struct TaskData
{
struct ExecBase *SysBase;
struct DosLibrary *DOSBase;
struct Library *UtilityBase;
struct Library *BBSReadBase;
struct Library *UTGuiBase;
struct BBSListItem *mybbs;
struct List *conflist;
struct List *farealist;
ULONG msgnr;
ULONG replyto;
TEXT from[NAMELENGTH];
TEXT to[NAMELENGTH];
TEXT confname[NAMELENGTH];
TEXT subject[NAMELENGTH];
BOOL private;
BOOL read;
ULONG time;
struct MinList linelist;
ULONG lines;
BPTR fh;
STRPTR errmsg;
APTR msgpool;
APTR confpool;
APTR pbar;
STRPTR pubscreen;
};
#define SysBase td->SysBase
#define DOSBase td->DOSBase
#define UtilityBase td->UtilityBase
#define BBSReadBase td->BBSReadBase
#define UTGuiBase td->UTGuiBase
#define mybbs td->mybbs
#define conflist td->conflist
#define farealist td->farealist
#define msgnr td->msgnr
#define replyto td->replyto
#define from td->from
#define to td->to
#define confname td->confname
#define subject td->subject
#define private td->private
#define read td->read
#define time td->time
#define linelist td->linelist
#define lines td->lines
#define fh td->fh
#define errmsg td->errmsg
#define msgpool td->msgpool
#define confpool td->confpool
#define pbar td->pbar
#define pubscreen td->pubscreen
extern STRPTR progname, progdate;
extern LONG version, revision;
/* Prototypes for external functions */
extern void * __asm AsmCreatePool(register __d0 ULONG, register __d1 ULONG, register __d2 ULONG, register __a6 struct ExecBase *);
extern void __asm AsmDeletePool(register __a0 void *, register __a6 struct ExecBase *);
extern void * __asm AsmAllocPooled(register __a0 void *, register __d0 ULONG, register __a6 struct ExecBase *);
extern void __asm AsmFreePooled(register __a0 void *, register __a1 void *, register __d0 ULONG, register __a6 struct ExecBase *);
extern APTR SPrintf(STRPTR dest, STRPTR fmtstr, ...);
extern struct Library *OpenBRLibrary(struct ExecBase *, struct DosLibrary *, STRPTR, LONG);
/* Prototypes for global functions */
struct Node * FindiName(struct List *list, STRPTR name);
BOOL DoMsgAdding(struct TaskData *td);
BOOL ParseConfList(struct TaskData *td);
BOOL ParseFileList(struct TaskData *td);
STRPTR MyStrTok(STRPTR *tokptr, STRPTR input);
UBYTE *StripAnsi(UBYTE *s);
STRPTR monthnames[] =
{
"January", "February", "March",
"April", "May", "June",
"July", "August", "September",
"October", "November", "December"
};
UBYTE *template = "BBSNAME,GRAB,PUBSCREEN/K,ARCHIVE/S,DELETE/S,USAGE/S";
enum {
TEM_BBSNAME,
TEM_GRAB,
TEM_PUBSCREEN,
TEM_ARCHIVE,
TEM_DELETE,
TEM_USAGE,
TEM_NUMBEROF
};
STRPTR fmtstr =
"%s V%ld.%ld\n"
"Usage: %s [bbsname] [grab] [PubScreen name] [ARCHIVE] [DELETE] [USAGE]\n"
"Copyright © Ultima Thule Software %s Author: Eivind Nordseth\n%s";
LONG __saveds NoName(void)
{
struct TaskData TaskData, *td;
struct GlobalConfig *cfg = NULL;
struct ConfListItem *myconf;
struct RDArgs *rdargs = NULL, *args = NULL;
BOOL newmsg = FALSE, findsubject = FALSE, getlines = FALSE, bufCopyBack = FALSE, addedMsgs = FALSE;
LONG array[TEM_NUMBEROF], retval = RETURN_FAIL, len, filelen, filepos;
struct List *bbslist = NULL;
STRPTR strp, foo, grab = NULL;
struct MinNode *node;
TEXT buf[BUFLEN], grabname[GRABLEN], tmpfile[GRABLEN];
BPTR lock, tmpfh = NULL;
UWORD charset;
setmem(td = &TaskData, sizeof(struct TaskData), 0);
SysBase = *(struct ExecBase **)4;
if(!(DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 0L))) return(10000L);
if(DOSBase->dl_lib.lib_Version < 37)
{
errmsg = "Needs Kick V37+";
goto quit;
}
if(!(UtilityBase = OpenLibrary("utility.library", 37L))) goto quit;
if(!(BBSReadBase = OpenBRLibrary(SysBase, DOSBase, BBSREADNAME, 3L)))
{
errmsg = "Needs bbsread.library V3+";
goto quit;
}
UTGuiBase = OpenBRLibrary(SysBase, DOSBase, "utgui.library", 1L);
if(!(args = AllocDosObject(DOS_RDARGS, NULL))) goto quit;
setmem(array, TEM_NUMBEROF * sizeof(LONG), 0);
SPrintf(args->RDA_ExtHelp = buf, fmtstr, progname, version, revision,
progname, progdate, template);
if(!(rdargs = ReadArgs(template, array, args)))
{
errmsg = "Error in arguments.";
goto quit;
}
if(array[TEM_USAGE] || !array[TEM_BBSNAME] || !array[TEM_GRAB])
{
Printf(fmtstr, progname, version, revision, progname, progdate, "");
retval = RETURN_OK;
goto quit;
}
pubscreen = (STRPTR) array[TEM_PUBSCREEN];
if(!(cfg = GetGlobalConfig())) { errmsg = "Error geting global config."; goto quit; }
if(!(ConfigGlobalTags(cfg, CG_BufCopyBack, TRUE, TAG_END))) { errmsg = "Error changing global config."; goto quit; }
bufCopyBack = TRUE;
if(!(bbslist = GetBBSList())) { errmsg = "Error geting bbslist."; goto quit; }
if(!(mybbs = (struct BBSListItem *) FindiName(bbslist, (STRPTR) array[TEM_BBSNAME])))
{
errmsg = "Unknown BBS";
goto quit;
}
StartOfAdding(mybbs);
if(mybbs->bl_Data->bd_Flags & BDF_ADD_USERS)
{
WriteBRUserTags(mybbs, WBRUSR_OnlyIfNotExist, TRUE, BRUSR_Name, "SYSOP", TAG_END);
}
if(!(conflist = GetConfList(mybbs))) { errmsg = "Error geting conflist."; goto quit; }
if(ParseConfList(td)) goto quit;
if(ParseFileList(td)) goto quit;
if(!(confpool = AsmCreatePool(MEMF_ANY, 1024, 512, SysBase)))
{
errmsg = "Out of memory";
goto quit;
}
/* Make a copy of all confnames in the correct conference charset. */
myconf = (struct ConfListItem *) &conflist->lh_Head;
while((myconf = (struct ConfListItem *)myconf->cl_Node.ln_Succ)->cl_Node.ln_Succ)
{
if((charset = ConfCharset(mybbs, myconf)) != BRCS_ISO)
{
if(!(myconf->cl_Node.ln_Name = AsmAllocPooled(confpool,
strlen(myconf->cl_Node.ln_Name) + 1, SysBase)))
{
errmsg = "Out of memory";
goto quit;
}
CharsetConvert(BRCS_ISO, charset, myconf->cl_Data->cd_Name,
myconf->cl_Node.ln_Name, 0);
}
}
if(!(lock = Lock((STRPTR) array[TEM_GRAB], ACCESS_READ)))
{
errmsg = "No grabfile";
goto done;
}
UnLock(lock);
if(array[TEM_ARCHIVE])
{
if(pubscreen && UTGuiBase)
{
if(!pbar)
{
if(!(pbar = ugOpenProgressBar(progname,
PB_Total, 1,
PB_ScreenName, pubscreen,
PB_AbortText, "_Abort",
PB_ProgressText, "Unarchiving grab",
PB_ProgressCWidth, 23,
TAG_END)))
{
errmsg = "Coundn't open progress bar";
goto quit;
}
}
else
{
if(ugUpdateProgressBar(pbar,
PB_Total, 1,
PB_Current, 0,
PB_ProgressText, "Unarchiving grab",
TAG_END)) goto done;
}
SPrintf(tmpfile, "t:ParseMsg.%08lx", FindTask(NULL));
tmpfh = Open(tmpfile, MODE_NEWFILE);
}
if(UnArchiveTags((STRPTR) array[TEM_GRAB],
UA_DestDir, mybbs->bl_BBSPath,
tmpfh ? SYS_Output : TAG_IGNORE, tmpfh,
TAG_END))
{
if(tmpfh)
{
Seek(tmpfh, 0, OFFSET_BEGINNING);
while(FGets(tmpfh, buf, BUFLEN - 1)) FPuts(Output(), buf);
}
errmsg = "Couldn't unarchive archive";
goto quit;
}
strncpy(grabname, mybbs->bl_BBSPath, GRABLEN);
AddPart(grabname, mybbs->bl_Data->bd_GrabName, GRABLEN);
grab = grabname;
}
else grab = (STRPTR) array[TEM_GRAB];
if(fh) Close(fh);
if(!(fh = Open(grab, MODE_OLDFILE)))
{
errmsg = "Unable to open grabfile";
goto quit;
}
Seek(fh, 0, OFFSET_END);
if((filelen = Seek(fh, 0, OFFSET_BEGINNING)) == -1)
{
errmsg = "Seek error";
goto quit;
}
filepos = 0;
if(pubscreen && UTGuiBase)
{
if(!pbar)
{
if(!(pbar = ugOpenProgressBar(progname,
PB_Total, filelen,
PB_ScreenName, pubscreen,
PB_AbortText, "_Abort",
PB_ProgressText, "Parsing messages",
PB_ProgressCWidth, 23,
TAG_END)))
{
errmsg = "Coundn't open progress bar";
goto quit;
}
}
else
{
if(ugUpdateProgressBar(pbar,
PB_Total, filelen,
PB_Current, filepos,
PB_ProgressText, "Parsing messages",
TAG_END)) goto done;
}
}
else PutStr(CSI "0 p\n\n\n\n");
NewList((struct List *)&linelist);
if(!(msgpool = AsmCreatePool(MEMF_ANY, 1024, 512, SysBase)))
{
errmsg = "Out of memory";
goto quit;
}
while(FGets(fh, buf, BUFLEN - 1))
{
filepos += strlen(buf);
if(findsubject)
{
if(!strncmp(buf, " Entered on ",14))
{
struct ClockData cd[1];
setmem(cd, sizeof(struct ClockData), '\0');
if(!isdigit(*(strp = &buf[14])))
{
while(*strp != ' ') if(!*(++strp)) goto datefail; /* Spool over ABBS day */
if(*strp) strp++;
}
cd->mday = atol(strp);
while(*strp != ' ') if(!*(++strp)) goto datefail; /* Spool over date str */
if(!*(foo = ++strp)) goto datefail;
while(*strp != ' ') if(!*(++strp)) goto datefail; /* Spool over month str */
if(strp[-1] == ',') strp[-1] = '\0';
*strp = '\0';
for(cd->month = 0; cd->month < 12; cd->month++)
if(!strcmp(foo, monthnames[cd->month])) break;
if(cd->month++ == 12) goto datefail;
if(!*(++strp)) goto datefail;
cd->year = atol(strp);
while(*strp != ' ') if(!*(++strp)) goto datefail; /* Spool over year */
if(!strncmp(strp, " at ", 4))
{
strp += 4;
strp[2] = '\0';
strp[5] = '\0';
cd->hour = atol(strp);
cd->min = atol(strp + 3); /* Calculate time */
}
time = Date2Amiga(cd);
datefail:
charset = 0;
}
if(!strncmp(buf, " Reply to msg",15))
{
strp = &buf[18];
while(*strp != '.') if(!*(strp++)) break;
*strp = '\0';
replyto = atol(&buf[18]);
}
if(!strncmp(buf, "Subject: ",9))
{
stccpy(subject, &buf[9], NAMELENGTH);
if(subject[strlen(subject) - 2] == '\r') subject[strlen(subject) - 2] = '\0';
findsubject = FALSE;
getlines = TRUE;
lines = 0;
FGets(fh, buf, BUFLEN - 1);
filepos += strlen(buf);
FGets(fh, buf, BUFLEN - 1);
filepos += strlen(buf);
continue;
}
}
if(newmsg)
{
/* FPuts(Output(), buf); */
confname[0] = to[0] = from[0] = '\0';
msgnr = ULONG_MAX;
private = FALSE;
read = FALSE;
time = 0 ;
strp = buf;
do
{
if(!*(++strp)) goto line1fail;
while(*strp != ' ') if(!*(++strp)) goto line1fail;
} while(strncmp(strp, " message",8));
*strp = '\0';
stccpy(confname, buf, NAMELENGTH);
while(*strp != '#') if(!*(++strp)) goto line1fail;
if(!*(foo = ++strp)) goto line1fail;
while(*strp != ' ') if(!*(++strp)) goto line1fail;
*strp = '\0';
msgnr = atol(foo);
while(*strp != ' ') if(!*(++strp)) goto line1fail;
if(!*(foo = ++strp)) goto line1fail;
do
{
if(!*(++strp)) goto line1fail;
while(*strp != ' ') if(!*(++strp)) goto line1fail;
} while(strncmp(strp, " to ",4));
*strp = '\0';
stccpy(from, foo, NAMELENGTH);
if(strlen(++strp) <= 3) goto line1fail;
foo = strp + 3;
*(strp = foo + strlen(foo) - 2) = '\0';
if(*(--strp) == '.')
{
*strp = '\0';
while(*(--strp) == ')')
{
while(*(--strp) != '(' && strp > foo);
if(*(strp) != '(') break;
if(!stricmp(strp, "(PRIVATE)")) private = TRUE;
if(!strcmp(strp, "(read)")) read = TRUE;
if(read || private) *(--strp) = '\0';
else break;
}
}
stccpy(to, foo, NAMELENGTH);
line1fail:
if(!confname[0]) stccpy(confname, "No Conf", NAMELENGTH);
if(!to[0]) stccpy(to, "Unknown", NAMELENGTH);
if(!from[0]) stccpy(from, "Unknown", NAMELENGTH);
newmsg = FALSE;
findsubject = TRUE;
}
len = strlen(buf);
if(buf[len > 2 ? len - 3 : 0] == '\r' && buf[len > 2 ? len - 2 : 1] == '\r')
{
if(msgnr)
{
if(DoMsgAdding(td))
{
errmsg = "Failure when adding message";
goto quit;
}
NewList((struct List *)&linelist);
AsmDeletePool(msgpool, SysBase);
if(!(msgpool = AsmCreatePool(MEMF_CLEAR, 1024, 512, SysBase)))
{
errmsg = "Out of memory";
goto quit;
}
addedMsgs = TRUE;
}
newmsg = TRUE;
getlines = FALSE;
}
if(getlines)
{
if(!(node = (struct MinNode *) AsmAllocPooled(msgpool, sizeof(struct MinNode) + 80, SysBase)))
{
errmsg = "Out of memory";
goto quit;
}
strp = (STRPTR) &node[1];
stccpy(strp, buf, 80);
if(strp[strlen(strp) - 2] == '\r') strp[strlen(strp) - 2] = '\0';
AddTail((struct List *)&linelist, (struct Node *) node);
lines++;
}
if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
{
errmsg = "***Break";
goto done;
}
if(pbar) if(ugUpdateProgressBar(pbar, PB_Current, filepos, TAG_END)) goto done;
}
if(lines)
{
if(DoMsgAdding(td))
{
errmsg = "Failure when adding message";
goto quit;
}
addedMsgs = TRUE;
}
if(fh) Close(fh);
fh = NULL;
if(!addedMsgs)
{
errmsg = "No messages to add";
goto quit;
}
if(array[TEM_DELETE]) DeleteFile((STRPTR) array[TEM_GRAB]);
done: /* All stuff is done */
retval = RETURN_OK;
Flush(Output());
quit:
if(pbar) ugCloseProgressBar(pbar);
else Write(Output(), CSI "1 p", 4);
if(tmpfh)
{
Close(tmpfh);
DeleteFile(tmpfile);
}
if(errmsg)
{
struct ReqToolsBase *ReqToolsBase = NULL;
if(pbar)
{
if(ReqToolsBase = (struct ReqToolsBase *) OpenLibrary(REQTOOLSNAME, 38))
{
rtEZRequestTags(errmsg, "_OK", NULL, NULL,
RT_ReqPos, REQPOS_CENTERSCR,
RT_PubScrName, pubscreen,
RTEZ_ReqTitle, progname,
RT_Underscore, '_',
TAG_END);
CloseLibrary((struct Library *) ReqToolsBase);
}
}
if(!ReqToolsBase)
{
Write(Output(), errmsg, strlen(errmsg));
Write(Output(), "\n", 1);
}
}
if(fh) Close(fh);
if(grab && array[TEM_ARCHIVE]) DeleteFile(grab);
if(cfg)
{
if(bufCopyBack) ConfigGlobalTags(cfg, CG_BufEndCopyBack, TRUE, TAG_END);
FreeBRObject(cfg);
}
if(mybbs) EndOfAdding(mybbs);
if(bbslist) FreeBRObject(bbslist);
if(conflist) FreeBRObject(conflist);
if(farealist) FreeBRObject(farealist);
if(rdargs) FreeArgs(rdargs);
if(args) FreeDosObject(DOS_RDARGS, args);
if(msgpool) AsmDeletePool(msgpool, SysBase);
if(confpool) AsmDeletePool(confpool, SysBase);
if(UTGuiBase) CloseLibrary(UTGuiBase);
if(BBSReadBase) CloseLibrary(BBSReadBase);
if(UtilityBase) CloseLibrary(UtilityBase);
CloseLibrary((struct Library *) DOSBase);
return(retval);
}
struct Node * FindiName(
struct List *list,
STRPTR name)
{
struct Node *node = (struct Node *) &list->lh_Head;
while((node = node->ln_Succ)->ln_Succ)
{
if(!stricmp(name, node->ln_Name)) return(node);
}
return(NULL);
}
/* returns error */
BOOL DoMsgAdding(
struct TaskData *td)
{
struct ConfListItem *myconf;
ULONG n = 0L;
STRPTR *linearray;
struct MinNode *node;
BOOL error = TRUE;
UWORD charset;
if(!lines) return(FALSE);
if(!(myconf = (struct ConfListItem *) FindiName(conflist, confname)))
{
/* Printf("New conference!\n"); */
if((charset = ConfCharset(mybbs, NULL)) != BRCS_ISO)
if(!CharsetConvert(charset, BRCS_ISO, confname, NULL, 0L)) goto fail;
if(!(myconf = ConfigConfTags(NULL,
CC_ConfList, conflist,
CC_AddToBBS, mybbs,
CC_ConfName, confname,
CC_SetConfFlags, CDF_MEMBER_OF,
TAG_END))) goto fail;
if(charset != BRCS_ISO) /* Convert conference name? */
{
if(!(myconf->cl_Node.ln_Name = AsmAllocPooled(confpool,
strlen(myconf->cl_Node.ln_Name) + 1, SysBase)))
{
errmsg = "Out of memory";
goto fail;
}
CharsetConvert(BRCS_ISO, charset, myconf->cl_Data->cd_Name,
myconf->cl_Node.ln_Name, 0);
}
}
else
{
charset = ConfCharset(mybbs, myconf);
if(!(myconf->cl_Data->cd_Flags & CDF_MEMBER_OF))
ConfigConfTags(myconf, CC_SetConfFlags, CDF_MEMBER_OF, TAG_END);
}
if(!(linearray = AsmAllocPooled(msgpool, (lines + 1) * sizeof(STRPTR), SysBase))) return(TRUE);
node = (struct MinNode *) &linelist.mlh_Head;
while((node = node->mln_Succ)->mln_Succ)
{
linearray[n] = (STRPTR) &node[1];
if(charset != BRCS_ISO) CharsetConvert(charset, BRCS_ISO, linearray[n], NULL, 0);
n++;
/* Printf("line %ld of %ld:%s\n", n, lines, &node[1]); */
}
if(n) { linearray[--n] = NULL; }
if(n) { if(!strlen(linearray[--n])) linearray[n] = NULL; }
if(charset != BRCS_ISO)
{
CharsetConvert(charset, BRCS_ISO, from, NULL, 0);
CharsetConvert(charset, BRCS_ISO, to, NULL, 0);
CharsetConvert(charset, BRCS_ISO, subject, NULL, 0);
}
if(!WriteBRMessageTags(myconf,
BRMSG_FromName, from,
(strcmp(to, "ALL") ? BRMSG_ToName : TAG_IGNORE), to,
BRMSG_OrginalNr, msgnr,
(replyto ? BRMSG_RefNr : TAG_IGNORE), replyto,
(time ? BRMSG_CreationDate : TAG_IGNORE), time,
BRMSG_Subject, subject,
BRMSG_Text, linearray,
WBRMSG_MarkMessage, TRUE,
WBRMSG_Private, private,
WBRMSG_Read, read,
TAG_END)) goto fail;
if(mybbs->bl_Data->bd_Flags & BDF_ADD_USERS || private)
{
WriteBRUserTags(mybbs, WBRUSR_OnlyIfNotExist, TRUE, BRUSR_Name, from, TAG_END);
if(strcmp(to, "ALL"))
WriteBRUserTags(mybbs, WBRUSR_OnlyIfNotExist, TRUE, BRUSR_Name, to, TAG_END);
}
error = FALSE;
fail:
if(!pbar || error)
{
if(!pbar) PutStr("\x9b\x34\x41");
Printf("Conf: %-30.s\nMsgnr: %5.ld Replyto: %5.ld\nFrom: %-30.s To: %-30.s\n",
myconf->cl_Data->cd_Name, msgnr, replyto, from, to);
Printf("Subject: %-60.s\n", subject);
}
lines = 0; replyto = 0;
return(error);
}
/****** parsemsg/ParseConfList ******************************************
*
* NAME
* ParseConfList -- Parses conference list.
*
* SYNOPSIS
* error = ParseConfList( td )
*
* BOOL ParseConfList( struct TaskData * );
*
* FUNCTION
* Parses conferences.txt and updates the conference list for a bbs.
* Dependant of SysBase, DOSBase, UtilityBase, BBSReadBase, UTGuiBase,
* mybbs, pubscreen, pbar and conflist defined in the TaskData structure.
*
* INPUTS
* td - TaskData structure.
*
* RESULT
* error - Boolean.
* The errmsg field in TaskData may be set to point to an error
* message if the function fails.
*
* EXAMPLE
*
* NOTES
*
* BUGS
*
* SEE ALSO
*
******************************************************************************
*
*/
BOOL ParseConfList(
struct TaskData *td)
{
struct ConfListItem *myconf, *nextconf;
struct PassConfListItem *passconf;
struct List list[1];
STRPTR foo, bits;
TEXT ct[BUFLEN], fname[GRABLEN];
BOOL bitdone, biterr, heading = TRUE, error = TRUE, delete = FALSE;
LONGBITS flags;
BPTR dofh = NULL;
APTR pool = NULL;
LONG filelen, filepos;
strncpy(fname, mybbs->bl_BBSPath, GRABLEN);
strncat(fname, "conferences.txt", GRABLEN - strlen(fname));
if(!(dofh = Open(fname, MODE_OLDFILE))) return(FALSE);
Seek(dofh, 0, OFFSET_END);
if((filelen = Seek(dofh, 0, OFFSET_BEGINNING)) == -1)
{
errmsg = "Seek error";
goto fail;
}
filepos = 0;
if(pubscreen && UTGuiBase)
{
if(!pbar)
{
if(!(pbar = ugOpenProgressBar(progname,
PB_Total, filelen,
PB_ScreenName, pubscreen,
PB_AbortText, "_Abort",
PB_ProgressText, "Parsing conference list",
PB_ProgressCWidth, 23,
TAG_END)))
{
errmsg = "Coundn't open progress bar";
goto fail;
}
}
else
{
if(ugUpdateProgressBar(pbar,
PB_Total, filelen,
PB_Current, filepos,
PB_ProgressText, "Parsing conference list",
TAG_END)) goto done;
}
}
else PutStr(CSI"0 p\n");
NewList(list);
if(!(pool = AsmCreatePool(MEMF_ANY, 512, 256, SysBase)))
{
errmsg = "Out of memory";
goto fail;
}
while(FGets(dofh, ct, BUFLEN - 1))
{
filepos += strlen(ct);
StripAnsi(ct);
if(heading)
{
if(!(strcmp(ct, "-----------------"))) heading = FALSE;
continue;
}
bits = ct;
while(*bits != ':') if(!*(++bits)) break;
if(!*bits) continue;
*bits = '\0';
foo = bits++ - 1;
while(foo > ct && *foo == ' ') *(foo--) = '\0';
if(foo == ct) continue;
bitdone = FALSE;
biterr = FALSE;
flags = 0;
while(!bitdone)
{
foo = ++bits;
while(*foo && *foo != '.' && *foo != ',') foo++;
if(!*foo)
{
biterr = TRUE;
break;
}
if(*foo == '.') bitdone = TRUE;
*(foo++) = '\0';
if(!strcmp(bits, "MAIL")) flags |= CDF_MAIL;
if(!strcmp(bits, "READ ONLY")) flags |= CDF_READ_ONLY;
if(!strcmp(bits, "Obligatory")) flags |= CDF_COMPULSORY;
if(!strcmp(bits, "FILE INFO")) flags |= CDF_FILE_INFO;
if(!strcmp(bits, "USER INFO")) flags |= CDF_USER_INFO;
if(!strcmp(bits, "Private allowed")) flags |= CDF_PRIVATE_ALLOWED;
if(!strcmp(bits, "Member")) flags |= CDF_MEMBER_OF;
if(!strcmp(bits, "Alias")) flags |= CDF_ALIAS | CDF_ENTER_ONLY_TO_ALL;
bits = foo;
}
if(biterr) continue;
if(!(passconf = AsmAllocPooled(pool, sizeof(struct PassConfListItem) + strlen(ct) + 1, SysBase)))
{
errmsg = "Out of memory";
goto fail;
}
strcpy(passconf->pl_Name = passconf->pl_Node.ln_Name = (STRPTR) &passconf[1], ct);
passconf->pl_Description = NULL;
passconf->pl_BBSConfNr = -1;
passconf->pl_Flags = flags;
AddTail(list, (struct Node *) passconf);
if(!pbar)
{
PutStr(CSI "A");
Printf("Conf: %-30.s, Flags: %l08x\n", ct, flags);
}
if((myconf = (struct ConfListItem *) FindiName(conflist, ct)) || (flags & CDF_MEMBER_OF))
{
if(!(myconf = ConfigConfTags(myconf, CC_ConfList, conflist,
CC_AddToBBS, mybbs, CC_ConfName, ct, CC_ClearConfFlags,
CDF_MEMBER_OF | CDF_MAIL | CDF_READ_ONLY | CDF_COMPULSORY | CDF_FILE_INFO
| CDF_USER_INFO | CDF_PRIVATE_ALLOWED | CDF_ENTER_ONLY_TO_ALL | CDF_ALIAS
| CDF_NOT_ON_BBS | CDF_REPLY_ONLY_TO_ALL | CDF_NO_LINEWRAP_DISPLAY,
CC_SetConfFlags, flags, TAG_END)))
{
if(pbar) Printf("Conf: %-30.s, Flags: %l08x\n", ct, flags);
errmsg = "ConfigConf() failed";
goto fail;
}
myconf->cl_UserData = (APTR) TRUE;
}
if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
{
errmsg = "***Break";
goto done;
}
if(pbar) if(ugUpdateProgressBar(pbar, PB_Current, filepos, TAG_END)) goto done;
}
nextconf = (struct ConfListItem *) conflist->lh_Head;
while(nextconf = (struct ConfListItem *) (myconf = nextconf)->cl_Node.ln_Succ)
{
struct ConfInternal *confint = myconf->cl_Internal;
if(confint->ci_LastMsg < confint->ci_FirstMsg
&& (!(myconf->cl_Data->cd_Flags & CDF_MEMBER_OF) || !myconf->cl_UserData))
{
ConfigConfTags(myconf, CC_DeleteConf, TRUE, TAG_END);
}
else
{
if(!myconf->cl_UserData)
ConfigConfTags(myconf,
CC_SetConfFlags, CDF_NOT_ON_BBS,
CC_ClearConfFlags, CDF_MEMBER_OF,
TAG_END);
}
}
if(WritePassiveConfList(mybbs, list))
{
errmsg = "WritePassiveConfList() failed";
goto fail;
}
delete = TRUE;
done:
error = FALSE;
fail:
if(pool) AsmDeletePool(pool, SysBase);
if(dofh) Close(dofh);
if(delete) DeleteFile(fname);
return(error);
}
/****** parsemsg/ParseFileList ******************************************
*
* NAME
* ParseFileList -- Adds files from newfiles.txt to the file database.
*
* SYNOPSIS
* error = ParseFileList( td )
*
* BOOL ParseFileList( struct TaskData * );
*
* FUNCTION
* Parses newfiles.txt and adds new files to the database. Dependant of
* SysBase, DOSBase, UtilityBase, BBSReadBase, UTGuiBase, mybbs,
* pubscreen, pbar and farealist defined in the TaskData structure.
*
* INPUTS
* td - TaskData structure.
*
* RESULT
* error - Boolean.
* The errmsg field in TaskData may be set to point to an error
* message if the function fails.
*
* EXAMPLE
*
* NOTES
*
* BUGS
*
* SEE ALSO
*
******************************************************************************
*
*/
BOOL ParseFileList(
struct TaskData *td)
{
struct FAreaListItem *farea = NULL;
struct SFileResult *found;
struct ClockData cd[1];
TEXT ct[BUFLEN], fname[GRABLEN];
BOOL error = TRUE, back = FALSE;
STRPTR file, date, kb, min, dlds, descr[2], np;
BPTR dofh = NULL;
LONG cnt, filelen, filepos;
strncpy(fname, mybbs->bl_BBSPath, GRABLEN);
AddPart(fname, "Newfiles.txt", GRABLEN);
if(!(dofh = Open(fname, MODE_OLDFILE))) return(FALSE);
Seek(dofh, 0, OFFSET_END);
if((filelen = Seek(dofh, 0, OFFSET_BEGINNING)) == -1)
{
errmsg = "Seek error";
goto fail;
}
if(FGets(dofh, ct, BUFLEN - 1))
{
if(!strcmp(ct, "DONE\n")) goto done;
}
filepos = 5;
if(pubscreen && UTGuiBase)
{
if(!pbar)
{
if(!(pbar = ugOpenProgressBar(progname,
PB_Total, filelen,
PB_ScreenName, pubscreen,
PB_AbortText, "_Abort",
PB_ProgressText, "Parsing newfiles",
PB_ProgressCWidth, 23,
TAG_END)))
{
errmsg = "Coundn't open progress bar";
goto fail;
}
}
else
{
if(ugUpdateProgressBar(pbar,
PB_Total, filelen,
PB_Current, filepos,
PB_ProgressText, "Parsing newfiles",
TAG_END)) goto done;
}
}
else PutStr(CSI"0 p\n");
if(!(farealist = GetFAreaList(mybbs)))
{
errmsg = "GetFAreaList() failed";
goto fail;
}
while(FGets(dofh, ct, BUFLEN - 1))
{
BOOL notdigit = FALSE;
filepos += strlen(ct);
StripAnsi(ct);
if(ct[0] == '(')
{
LONG len = strlen(ct) - 1;
if(ct[len] != ')') continue;
if(len > 1)
{
ct[len] = '\0';
strcpy(fname, &ct[1]);
if(!(farea = (struct FAreaListItem *) FindiName(farealist, fname)))
{
if(!(farea = ConfigFAreaTags(NULL,
CFA_FAreaList, farealist,
CFA_AddToBBS, mybbs,
CFA_Name, fname, TAG_END)))
{
errmsg = "ConfigFArea() failed";
goto fail;
}
}
cnt = 3; /* Skip farea header */
}
else farea = NULL;
continue;
}
if(!farea) continue;
if(cnt) if(cnt--) continue;
if(strlen(ct) < 40) continue;
if(!(np = MyStrTok(&file, &ct[2]))) continue;
if(!(np = MyStrTok(&date, np))) continue;
if(!(np = MyStrTok(&kb, np))) continue;
if(!(np = MyStrTok(&min, np))) continue;
if(!(descr[0] = MyStrTok(&dlds, np))) continue;
descr[1] = NULL;
for(np = date; *np; np++)
if(!isdigit(*np))
notdigit = TRUE;
if(!isdigit(*kb)) notdigit = TRUE;
if(!isdigit(*min)) notdigit = TRUE;
for(np = dlds; *np; np++)
if(!isdigit(*np))
notdigit = TRUE;
if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
{
errmsg = "***Break";
goto done;
}
if(pbar) if(ugUpdateProgressBar(pbar, PB_Current, filepos, TAG_END)) goto done;
if(!descr[0] || notdigit) continue;
if(found = SearchBRFileTags(
SBRF_SearchFAreaList, farealist,
SBRF_SearchStr, file,
SBRF_SearchName, TRUE,
SBRF_SearchAll, FALSE,
TAG_END))
{
if(found->fr_FilesFound)
{
if(found->fr_Files[0].ff_FArea == farea)
{
APTR obj;
struct TagItem *tags;
BOOL equal = FALSE;
if(obj = ReadBRFileTags(found->fr_Files[0].ff_FArea, found->fr_Files[0].ff_FileNr,
RBRF_FileTagsPtr, &tags, TAG_END))
{
if(atol(dlds) == GetTagData(BRFILE_Downloads, 0, tags)) equal = TRUE;
FreeBRObject(obj);
}
if(equal == TRUE) continue;
}
WriteBRFileTags(farea,
WBRF_UpdateFileNr, found->fr_Files[0].ff_FileNr,
WBRF_DeleteFile, TRUE,
TAG_END);
}
FreeBRObject(found);
}
setmem(cd, sizeof(struct ClockData), '\0');
cd->mday = atol(&date[4]);
date[4] = '\0';
cd->month = atol(&date[2]);
date[2] = '\0';
cd->year = atol(date);
if(cd->year < 78) cd->year += 2000;
else cd->year += 1900;
time = Date2Amiga(cd);
if(!pbar)
{
if(back) PutStr(CSI "2A");
back = TRUE;
Printf("Farea: %-20.s File:%-16.s\nDescr: %-40.s\n",
farea->al_Data->ad_Name, file, descr[0]);
}
if(!WriteBRFileTags(farea,
BRFILE_Name, file,
BRFILE_Date, time,
BRFILE_Size, atol(kb) * 1024,
BRFILE_Downloads, atol(dlds),
BRFILE_Description, descr, TAG_END))
{
if(pbar) Printf("Farea: %-20.s File:%-16.s\nDescr: %-40.s\n",
farea->al_Data->ad_Name, file, descr[0]);
errmsg = "WriteBRFile() failed";
goto fail;
}
}
Seek(dofh, 0 , OFFSET_BEGINNING);
FPuts(dofh, "DONE\n");
done:
error = FALSE;
fail:
if(dofh) Close(dofh);
return(error);
}
STRPTR MyStrTok(
STRPTR *tokptr,
STRPTR input)
{
*tokptr = NULL;
if(!input) return(NULL);
while(*input && *input == ' ') input++;
if(!*input) return(NULL);
*tokptr = input;
while(*input && *input != ' ') input++;
if(!*input) return(NULL);
*input = '\0';
return(input + 1);
}
UBYTE *StripAnsi(UBYTE *s)
{
STRPTR dest = s, d = s;
while(*s)
{
if((*s == 0x1b) || (*s == 0x9b))
{
if(*s == 0x1b)
{
if(*++s != '[') continue;
}
s++;
while(*s && *s < '@') s++;
}
else if(*s >= 32) *d++ = *s;
s++;
}
*d = '\0';
return(dest);
}